package com.lungle.warmdiary.app;

import android.app.Notification;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

import com.bugtags.library.Bugtags;
import com.lungle.warmdiary.R;
import com.lungle.warmdiary.app.base.BaseApplication;
import com.lungle.warmdiary.app.model.response.User;
import com.lungle.warmdiary.app.utils.CyptoUtils;
import com.lungle.warmdiary.app.utils.LogUtils;
import com.lungle.warmdiary.app.utils.MethodsCompat;
import com.lungle.warmdiary.app.utils.StringUtils;
import com.lungle.warmdiary.app.utils.TDevice;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.umeng.commonsdk.UMConfigure;
import com.umeng.message.IUmengRegisterCallback;
import com.umeng.message.MsgConstant;
import com.umeng.message.PushAgent;
import com.umeng.message.UTrack;
import com.umeng.message.UmengMessageHandler;
import com.umeng.message.UmengNotificationClickHandler;
import com.umeng.message.entity.UMessage;

import java.io.File;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;


public class AppContext extends BaseApplication {

    private static final String KEY_APP_ID = "key_app_id";
    private static final String KEY_FRIST_INIT_PUSH = "jpush_init";
    private static final String KEY_APK_SIGNATURE = "apk signature";
    private static final String KEY_HAS_MEDIA_ACCOUNT = "has_media_account";
    //    public static final String KEY_READ_TESTER = "has_read_tester";
    public static final String CUSTOM = "custom";


    private static AppContext instance;
    private static int loginUserId;
    private boolean login;

    public static boolean sslLock;
    public static boolean openRelease;
    public static boolean openCustom;

    public static volatile boolean shouldShowReloadin = true;

    private Handler handler;
    private static final String TAG = AppContext.class.getName();
    public static final String UPDATE_STATUS_ACTION = "com.umeng.message.example.action.UPDATE_STATUS";


    @Override
    public void onCreate() {
        super.onCreate();
        // Thread.setDefaultUncaughtExceptionHandler(AppException.getAppExceptionHandler());
        instance = this;
        initImageLoader(this);
        initUmeng();
//        JPushService.start(this);
        initLoginInfo();

        initBugtags();
        loadSslLock();
        if ("true".equals(instance.getProperty("debug_on"))) {
            openRelease = true;
        }
        String customUrl = instance.getProperty(CUSTOM);
        if (!TextUtils.isEmpty(customUrl) && StringUtils.isUrl(customUrl)) {
            openCustom = true;
            openRelease = false;
        }

    }

    private void loadSslLock() {
        try {
            Bundle bundle = getApplicationBundle();
            sslLock = bundle.getBoolean("CSO_SSLLOCK");
        } catch (Throwable throwable) {
            Log.w("wemedia", "load bundle error.");
        }
    }

    private void initUmeng() {
//        PlatformConfig.setSinaWeibo(AppConstant.SINA_WEIBO_ID, AppConstant.SINA_WEIBO_SECRET);
//        PlatformConfig.setWeixin(AppConstant.WEICHAT_APPID, AppConstant.WEICHAT_SECRET);
//        PlatformConfig.setQQZone(AppConstant.QQ_APPID, AppConstant.QQ_APPKEY);

        UMConfigure.setLogEnabled(true);
        //初始化组件化基础库, 统计SDK/推送SDK/分享SDK都必须调用此初始化接口
        //UMConfigure.init(Context context, String appkey, String channel, int deviceType, String pushSecret);
        UMConfigure.init(this, AppConstant.UMEMG_APPKEY, "dev", UMConfigure.DEVICE_TYPE_PHONE,
                AppConstant.UMENG_SECRET);
        //PushSDK初始化(如使用推送SDK，必须调用此方法)
        initUpush();
    }

    private void initUpush() {
        PushAgent mPushAgent = PushAgent.getInstance(this);
        handler = new Handler(getMainLooper());

        //sdk开启通知声音
        mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SDK_ENABLE);
        // sdk关闭通知声音
        // mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SDK_DISABLE);
        // 通知声音由服务端控制
        // mPushAgent.setNotificationPlaySound(MsgConstant.NOTIFICATION_PLAY_SERVER);

        // mPushAgent.setNotificationPlayLights(MsgConstant.NOTIFICATION_PLAY_SDK_DISABLE);
        // mPushAgent.setNotificationPlayVibrate(MsgConstant.NOTIFICATION_PLAY_SDK_DISABLE);

        UmengMessageHandler messageHandler = new UmengMessageHandler() {

            /**
             * 通知的回调方法（通知送达时会回调）
             */
            @Override
            public void dealWithNotificationMessage(Context context, UMessage msg) {
                //调用super，会展示通知，不调用super，则不展示通知。
                super.dealWithNotificationMessage(context, msg);
            }

            /**
             * 自定义消息的回调方法
             */
            @Override
            public void dealWithCustomMessage(final Context context, final UMessage msg) {

                handler.post(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        // 对自定义消息的处理方式，点击或者忽略
                        boolean isClickOrDismissed = true;
                        if (isClickOrDismissed) {
                            //自定义消息的点击统计
                            UTrack.getInstance(getApplicationContext()).trackMsgClick(msg);
                        } else {
                            //自定义消息的忽略统计
                            UTrack.getInstance(getApplicationContext()).trackMsgDismissed(msg);
                        }
                        Toast.makeText(context, msg.custom, Toast.LENGTH_LONG).show();
                    }
                });
            }

            /**
             * 自定义通知栏样式的回调方法
             */
            @Override
            public Notification getNotification(Context context, UMessage msg) {
                switch (msg.builder_id) {
                    case 1:
                        Notification.Builder builder = new Notification.Builder(context);
                        RemoteViews myNotificationView = new RemoteViews(context.getPackageName(),
                                R.layout.notification_view);
                        myNotificationView.setTextViewText(R.id.notification_title, msg.title);
                        myNotificationView.setTextViewText(R.id.notification_text, msg.text);
                        myNotificationView.setImageViewBitmap(R.id.notification_large_icon, getLargeIcon(context, msg));
                        myNotificationView.setImageViewResource(R.id.notification_small_icon,
                                getSmallIconId(context, msg));
                        builder.setContent(myNotificationView)
                                .setSmallIcon(getSmallIconId(context, msg))
                                .setTicker(msg.ticker)
                                .setAutoCancel(true);

                        return builder.getNotification();
                    default:
                        //默认为0，若填写的builder_id并不存在，也使用默认。
                        return super.getNotification(context, msg);
                }
            }
        };
        mPushAgent.setMessageHandler(messageHandler);

        /**
         * 自定义行为的回调处理，参考文档：高级功能-通知的展示及提醒-自定义通知打开动作
         * UmengNotificationClickHandler是在BroadcastReceiver中被调用，故
         * 如果需启动Activity，需添加Intent.FLAG_ACTIVITY_NEW_TASK
         * */
        UmengNotificationClickHandler notificationClickHandler = new UmengNotificationClickHandler() {

            @Override
            public void launchApp(Context context, UMessage msg) {
                super.launchApp(context, msg);
            }

            @Override
            public void openUrl(Context context, UMessage msg) {
                super.openUrl(context, msg);
            }

            @Override
            public void openActivity(Context context, UMessage msg) {
                super.openActivity(context, msg);
            }

            @Override
            public void dealWithCustomAction(Context context, UMessage msg) {
                Toast.makeText(context, msg.custom, Toast.LENGTH_LONG).show();
            }
        };
        //使用自定义的NotificationHandler
        mPushAgent.setNotificationClickHandler(notificationClickHandler);

        //注册推送服务 每次调用register都会回调该接口
        mPushAgent.register(new IUmengRegisterCallback() {
            @Override
            public void onSuccess(String deviceToken) {
                Log.i(TAG, "device token: " + deviceToken);
                sendBroadcast(new Intent(UPDATE_STATUS_ACTION));
            }

            @Override
            public void onFailure(String s, String s1) {
                Log.i(TAG, "register failed: " + s + " " + s1);
                sendBroadcast(new Intent(UPDATE_STATUS_ACTION));
            }
        });

        //使用完全自定义处理
        //mPushAgent.setPushIntentServiceClass(UmengNotificationService.class);

        //小米通道
        //MiPushRegistar.register(this, XIAOMI_ID, XIAOMI_KEY);
        //华为通道
        //HuaWeiRegister.register(this);
        //魅族通道
        //MeizuRegister.register(this, MEIZU_APPID, MEIZU_APPKEY);
    }

    private Bundle getApplicationBundle() throws NameNotFoundException {
        return getPackageManager()
                .getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA)
                .metaData;
    }

    private void initBugtags() {
        Bugtags.start("89f2b1d97b1785563ebff74bd8440d8f", this, Bugtags.BTGInvocationEventBubble);
//        try {
//            Bundle metaBundle = getApplicationBundle();
//            String appKey = metaBundle.getString("BUGTAG_APPKEY");
//            int invocation = metaBundle.getInt("BUGTAG_BTGInvocation");
//            String urlFilter = metaBundle.getString("BUGTAG_NWFILTER");
//            BugtagsOptions options = new BugtagsOptions.Builder().trackingNetworkURLFilter(urlFilter).build();
//            Bugtags.start("89f2b1d97b1785563ebff74bd8440d8f", this, invocation, options);
//            boolean insta = metaBundle.getBoolean("BUGTAG_INSTA");
//            if (insta) {
//                Bugtags.registerPlugin(new BugtagsInsta());
//            }
//        } catch (Throwable throwable) {
//            Log.w("wemedia", "init bugtags failed.", throwable);
//        }
    }

    public static AppContext getInstance() {
        return instance;
    }


    public void initImageLoader(Context context) {
        DisplayImageOptions displayOptions = new DisplayImageOptions.Builder()
//                .displayer(new CircleBitmapDisplayer())
//                .displayer(new com.lungle.warmdiary.app.utils.RoundedBitmapDisplayer(5,5))
                .imageScaleType(ImageScaleType.EXACTLY)
                .showImageOnLoading(R.drawable.iconplaceholder)
                .showImageForEmptyUri(R.drawable.iconplaceholder)
                .cacheInMemory(true).cacheOnDisk(true)
                .displayer(new FadeInBitmapDisplayer(100))
                .bitmapConfig(Config.RGB_565).build();
        // This configuration tuning is custom. You can tune every option, you
        // may tune some of them,
        // or you can create default configuration by
        // ImageLoaderConfiguration.createDefault(this);
        // method.
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                context).threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                .diskCacheFileNameGenerator(new Md5FileNameGenerator())
                .diskCacheSize(50 * 1024 * 1024)
                // 50 Mb
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                .imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000))// connectTimeout (5 s), readTimeout (30 s)超时时间
                //.writeDebugLogs() // Remove for release app
                .defaultDisplayImageOptions(displayOptions).build();
        // Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config);
    }


    /**
     * 判断当前版本是否兼容目标版本的方法
     *
     * @param VersionCode
     * @return
     */
    public boolean isMethodsCompat(int VersionCode) {
        int currentVersion = android.os.Build.VERSION.SDK_INT;
        return currentVersion >= VersionCode;
    }


    public PackageInfo getPackageInfo() {
        PackageInfo info = null;
        try {
            info = getPackageManager().getPackageInfo(getPackageName(), 0);
        } catch (NameNotFoundException e) {
            e.printStackTrace(System.err);
        }
        if (info == null)
            info = new PackageInfo();
        return info;
    }


    public String getAppId() {
        String uniqueID = getProperty(KEY_APP_ID);
        if (StringUtils.isEmpty(uniqueID)) {
            uniqueID = UUID.randomUUID().toString();
            setProperty(KEY_APP_ID, uniqueID);
        }
        return uniqueID;
    }


    public boolean isLogin() {
        return login;
    }


    public int getLoginUid() {
        return StringUtils.toInt(getProperty("user.userid"), 0);
    }

    public void setLoginUid(int uid) {
        setProperty("user.userid", uid + "");
    }


    public void cleanToken() {
        removeProperty("user.token");
    }

    public String getToken() {
        return getProperty("user.token");
    }

    public void setToken(String token) {
        setProperty("user.token", token);
    }


    public static void setOpenRelease(boolean openRelease) {

        if (openRelease) {
            AppContext.getInstance().setProperty("debug_on", "true");
        } else {
            AppContext.getInstance().removeProperty("debug_on");
        }
        AppContext.openRelease = openRelease;
    }


    public static void setOpenCustom(String url) {

        if (TextUtils.isEmpty(url)) {
            AppContext.getInstance().removeProperty(CUSTOM);
            AppContext.openCustom = false;
        } else if (!StringUtils.isUrl(url)) {
            showToast(url + " 不是正常的url");
            AppContext.getInstance().removeProperty(CUSTOM);
            AppContext.openCustom = false;
        } else {
            if (!url.endsWith("/"))
                url = url + "/";
            AppContext.getInstance().setProperty(CUSTOM, url);
            AppContext.openCustom = true;
            AppContext.openRelease = false;
        }

    }

    /**
     * 用户注销
     */
    public void Logout() {
        cleanToken();
        cleanLoginInfo();
        removeProperty(KEY_HAS_MEDIA_ACCOUNT);
        login = false;

    }


    public void initLoginInfo() {
        User loginUser = getLoginUser();
        if (loginUser != null && loginUser.getUserid() > 0
                && !TextUtils.isEmpty(getToken())) {// &&
            login = true;
            loginUserId = loginUser.getUserid();
        } else {
            this.Logout();
        }
    }


    public void saveLoginInfo(@NonNull final User user) {
        if (user.getCellphone() != null) setProperty("user.cellphone", user.getCellphone());
        if (user.getUsername() != null) setProperty("user.username", user.getUsername());
        if (user.getPassword() != null)
            setProperty("user.password", CyptoUtils.encode("wemedia", user.getPassword()));
        if (user.getGender() != null)
            setProperty("user.gender", String.valueOf(user.getGender()));
        if (user.getEmail() != null) setProperty("user.email", user.getEmail());
        if (user.getBirthday() != null) setProperty("user.birthday", user.getBirthday());
        if (user.getQq() != null) setProperty("user.qq", user.getQq());

    }


    public User getLoginUser() {
        User lu = new User();
        lu.setCellphone(getProperty("user.cellphone"));
        lu.setUserid(StringUtils.toInt(getProperty("user.userid"), 0));
        lu.setUsername(getProperty("user.username"));
        lu.setPassword(CyptoUtils.decode("wemedia", getProperty("user.pwd")));
        if (getProperty("user.gender") != null)
            lu.setGender(Integer.valueOf(getProperty("user.gender")));
        lu.setEmail(getProperty("user.email"));
        lu.setBirthday(getProperty("user.birthday"));
        lu.setQq(getProperty("user.qq"));
        return lu;
    }

    public void cleanLoginInfo() {
        removeProperty("user.userid", "user.username", "user.qq",
                "user.pwd", "user.gender", "user.email", "user.birthday", "user.cellphone");
    }


    /**
     * 清除app缓存
     */
    public void clearAppCache() {
//        removeProperty(KEY_READ_TESTER);
        deleteDatabase("webview.db");
        deleteDatabase("webview.db-shm");
        deleteDatabase("webview.db-wal");
        deleteDatabase("webviewCache.db");
        deleteDatabase("webviewCache.db-shm");
        deleteDatabase("webviewCache.db-wal");
        // 清除数据缓存
        clearCacheFolder(getFilesDir(), System.currentTimeMillis());
        clearCacheFolder(getCacheDir(), System.currentTimeMillis());
        // 2.2版本才有将应用缓存转移到sd卡的功能
        if (isMethodsCompat(android.os.Build.VERSION_CODES.FROYO)) {
            clearCacheFolder(MethodsCompat.getExternalCacheDir(this),
                    System.currentTimeMillis());
        }
    }


    private int clearCacheFolder(File dir, long curTime) {
        int deletedFiles = 0;
        if (dir != null && dir.isDirectory()) {
            try {
                for (File child : dir.listFiles()) {
                    if (child.isDirectory()) {
                        deletedFiles += clearCacheFolder(child, curTime);
                    }
                    if (child.lastModified() < curTime) {
                        if (child.delete()) {
                            deletedFiles++;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return deletedFiles;
    }

    public static void setProperty(String key, String value) {
        Editor editor = getPreferences().edit();
        editor.putString(key, value);
        apply(editor);
    }

    public static String getProperty(String key) {
        return getPreferences().getString(key, null);
    }

    public static void removeProperty(String... keys) {
        for (String key : keys) {
            Editor editor = getPreferences().edit();
            editor.putString(key, null);
            apply(editor);
        }
    }


    public void setFristInitJPush() {
        Editor edit = getPreferences().edit();
        edit.putBoolean(KEY_FRIST_INIT_PUSH, true);
        apply(edit);
    }

    public void saveSignature(String signature) {
        Editor edit = getPreferences().edit();
        edit.putString(KEY_APK_SIGNATURE, signature);
        apply(edit);
    }

    public String getSignature() {
        String text = getPreferences().getString(KEY_APK_SIGNATURE, "");
        if (TextUtils.isEmpty(text)) {
            Signature signature = TDevice.getPackageSignature(this, getPackageName());
            try {
                text = StringUtils.hexToString(CyptoUtils.getMd5(signature.toByteArray()));
                saveSignature(text);
            } catch (NoSuchAlgorithmException e) {
                LogUtils.printLogI(e.getMessage());
            }

        }

        return text;
    }

    public static boolean isFristInitJPush() {
        return getPreferences().getBoolean(KEY_FRIST_INIT_PUSH, false);
    }

    public static boolean hasMediaAccount() {
        return getPreferences().getBoolean(KEY_HAS_MEDIA_ACCOUNT, false);
    }

    public static void setMeidaAccount(boolean value) {
        Editor editor = getPreferences().edit();
        editor.putBoolean(KEY_HAS_MEDIA_ACCOUNT, value);
        apply(editor);
    }

    public static AppContext instance() {
        return instance;
    }


    public static void setIndustry(String key, String url, String name) {
        Editor editor = getPreferences().edit();
        editor.putString(String.format("industry_url_%s", key), url);
        editor.putString(String.format("industry_name_%s", key), name);
        apply(editor);
    }

    public static void setIndustryNum(int num) {
        Editor editor = getPreferences().edit();
        editor.putInt("industry_num", num);
        apply(editor);
    }

    public static int getIndustryNum() {
        return getPreferences().getInt("industry_num", 0);

    }

    public static String getIndustryUrl(String key) {
        return getPreferences().getString(String.format("industry_url_%s", key), "");
    }

    public static String getIndustryName(String key) {
        return getPreferences().getString(String.format("industry_name_%s", key), "");
    }

    public static void setTesterApply(String industryid, String content) {
        Editor editor = getPreferences().edit();
        editor.putString(String.format("industry_apply_%s", industryid), content);
        apply(editor);
    }

    public static void removeTesterApply(String industryid) {
        removeProperty(String.format("industry_apply_%s", industryid));
    }

    public static String getTesterApply(String industryid) {
        return getPreferences().getString(String.format("industry_apply_%s", industryid), "");
    }


    public static void setShare(String content) {
        Editor editor = getPreferences().edit();
        editor.putString("share_string", content);
        apply(editor);
    }


    public static String getShare() {
        return getPreferences().getString("share_string", "");
    }

}
